博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
怎样使用React Context API
阅读量:6091 次
发布时间:2019-06-20

本文共 5563 字,大约阅读时间需要 18 分钟。

翻译:疯狂的技术宅
原文:

本文首发微信公众号:jingchengyideng

欢迎关注,每天都给你推送新鲜的前端技术文章


React 现在已经成为一个实验性功能,但是只有在 React 中才能用在生产中。本文将向你展示两个基本的 Web 商店应用程序,一个使用了 Context API 进行构建,另一个则不用。

这个新的API解决了一个严重的问题 ——prop drilling。 即使你不熟悉这个术语,如果你曾经用 React.js 做过开发,它可能就已经在你身上发生过了。 Prop drilling 是通过将数据传递到多个中间 React 组件层,将数据从组件A 获取到组件 Z 的过程。 组件将间接的接收props,而你必须确保一切正常。

我们先探讨如何在没有 React Context API 的情况下处理常见问题:

App.js

class App extends Component {    state = {        cars: {            car001: { name: 'Honda', price: 100 },            car002: { name: 'BMW', price: 150 },            car003: { name: 'Mercedes', price: 200 }        }    };    incrementCarPrice = this.incrementCarPrice.bind(this);    decrementCarPrice = this.decrementCarPrice.bind(this);    incrementCarPrice(selectedID) {        // a simple method that manipulates the state        const cars = Object.assign({}, this.state.cars);        cars[selectedID].price = cars[selectedID].price + 1;        this.setState({            cars        });    }    decrementCarPrice(selectedID) {        // a simple method that manipulates the state        const cars = Object.assign({}, this.state.cars);        cars[selectedID].price = cars[selectedID].price - 1;        this.setState({            cars        });    }    render() {        return (            
logo

Welcome to my web store

{/* Pass props twice */}
); }}

ProductList .js

const ProductList = props => (    

Product list:

{/* Pass props twice */}
{/* Other potential product categories which we will skip for this demo: */} {/*
*/} {/*
*/} {/*
*/}
);export default ProductList;

Cars.js

const Cars = props => (    

Cars:

{/* Finally we can use data */} {Object.keys(props.cars).map(carID => (
props.incrementCarPrice(carID)} decrementPrice={() => props.decrementCarPrice(carID)} /> ))}
);

Car.js

const Cars = props => (    

Name: {props.name}

Price: ${props.price}

);

当然,这不是处理数据的最好方式,但我希望能够用它说明为什么 prop drilling 很差劲。 那么 Context API 是如何帮我们避免这种情况呢?

介绍Context Web Store

让我们重构程序并演示它可以做些什么。 简而言之,Context API 允许你拥有一个存储数据的中央存储(是的,就像存储在 Redux 中一样)。你可以把任何组件直接插入到商店应用中,也可以切断 middleman!

两个状态流的示例:一个使用React Context API,另一个不用

重构非常简单 —— 我们不必对组件的结构进行任何修改。但是我们确实需要创建一些新组件:Provider 和 consumer。

1.初始化 Context

首先,我们需要,后面可以使用它来创建 Provider 和 consumer。

MyContext.js

import React from 'react';// this is the equivalent to the createStore method of Redux// https://redux.js.org/api/createstoreconst MyContext = React.createContext();export default MyContext;

2. 创建 Provider

完成后,我们可以导入 context 并用它来创建我们的 provider,我们称之为 MyProvider。在里面使用一些值初始化一个状态,你可以通过 value prop 共享我们的 provider 组件。 在例子中,我们将共享 this.state.cars 以及一些操纵状态的方法。 将这些方法可以看作是 Redux 中的 Reducer。

MyProvider.js

import MyContext from './MyContext';class MyProvider extends Component {    state = {        cars: {            car001: { name: 'Honda', price: 100 },            car002: { name: 'BMW', price: 150 },            car003: { name: 'Mercedes', price: 200 }        }    };    render() {        return (            
{ const cars = Object.assign({}, this.state.cars); cars[selectedID].price = cars[selectedID].price + 1; this.setState({ cars }); }, decrementPrice: selectedID => { const cars = Object.assign({}, this.state.cars); cars[selectedID].price = cars[selectedID].price - 1; this.setState({ cars }); } }} > {this.props.children}
); }}

为了使 provider 可以访问其他组件,我们需要用它包装我们的应用程序(没错,就像 Redux 一样)。我们可以摆脱这些状态和方法,因为它们在 MyProvider.js 中定义。

App.js

class App extends Component {    render() {        return (            
logo

Welcome to my web store

); }}

3. 创建 Consumer

我们需要再次导入 context 并用它包装我们的组件,它会在组件中注入context 参数。 之后,它非常直接。 你使用 context 就像用 props 一样。 它包含我们在 MyProducer 中共享的所有值,我们所需要做的只是去使用它!

Cars.js

const Cars = () => (    
{context => (

Cars:

{Object.keys(context.cars).map(carID => (
context.incrementPrice(carID)} decrementPrice={() => context.decrementPrice(carID)} /> ))}
)}
);

我们似乎忘记了什么?是 ProductList !它使好处变得非常明显。 我们不必传递任何数据或方法。这个组件被简化,因为它只需要去渲染一些组件。

ProductList.js

const ProductList = () => (    

Product list:

{/* Other potential product categories which we will skip for this demo: */} {/*
*/} {/*
*/} {/*
*/}
);

在本文中,我对 Redux 和 Context API 进行了一些比较。 Redux 最大的优势之一就是你的应用可以拥有一个可以从任何组件访问的中央存储。而使用新的 Context API,默认情况下你已经有了这个功能。 在巨大的宣传攻势下 Context API 将会使 Redux 变得过时。

对于那些只把 Redux 作为中央存储功能的人来说,可能确实如此。 如果你只使用 Redux 的这一个功能,现在可以使用 Context API 替换它,并避免在不使用第三方库的情况下进行 prop drilling。


本文首发微信公众号:jingchengyideng

欢迎关注,每天都给你推送新鲜的前端技术文章


转载地址:http://ftvwa.baihongyu.com/

你可能感兴趣的文章
ODI基于源表时间戳字段获取增量数据
查看>>
并发容器之CopyOnWriteArrayList(转载)
查看>>
什么是AAC音频格式 AAC-LC 和 AAC-HE的区别是什么
查看>>
原创:goldengate从11.2升级到12.1.2
查看>>
Quartz
查看>>
正则表达式的语法规则
查看>>
C#一个关于委托和事件通俗易懂的例子
查看>>
类似于SVN的文档内容差异对比工具winmerge
查看>>
Cause: java.sql.SQLException: The user specified as a definer ('root'@'%') does not exist
查看>>
quratz线程
查看>>
execnet: rapid multi-Python deployment
查看>>
windows修改3389端口
查看>>
关于JavaScript词法
查看>>
FreeSwitch中的会议功能(4)
查看>>
MySQL中创建用户分配权限(到指定数据库或者指定数据库表中)
查看>>
AutoReleasePool 和 ARC 以及Garbage Collection
查看>>
重新想象 Windows 8 Store Apps (9) - 控件之 ScrollViewer 基础
查看>>
乐在其中设计模式(C#) - 提供者模式(Provider Pattern)
查看>>
MVP Community Camp 社区大课堂
查看>>
GWT用frame调用JSP
查看>>